﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BLL = KC.Business.Stockmaster;
using System.Collections.Specialized;

namespace KC.Presentation.Stockmaster
{
	public partial class Buy : Form
	{
		private string username, password, ticker;
		private double Price, Commission;

		public Buy(string Username, string Password, string Ticker)
		{
			InitializeComponent();

			if (string.IsNullOrEmpty(Username) | string.IsNullOrEmpty(Password) | string.IsNullOrEmpty(Ticker))
				return;

			username = Username;
			password = Password;
			ticker = Ticker;
			Text = "Buy " + ticker.ToUpper();
			label1.Text = "Buy how many shares of " + ticker.ToUpper() + "?";
		}

		private void Buy_Load(object sender, EventArgs e)
		{
			if (ticker.ToUpper().Trim() == username.ToUpper().Trim()) {
				DialogResult = System.Windows.Forms.DialogResult.Cancel;
				Close();
				return; }

			txtSuggestions.Text = "Looking up " + ticker.ToUpper() + "...";
			btnBuy.Enabled = false;
			slider.Enabled = false;
			bgw.RunWorkerAsync();
		}

		private void slider_Scroll(object sender, EventArgs e)
		{
			lblNumShares.Text = slider.Value.ToString("###,###,###") + " Shares";
			lblGrossCost.Text = "Subtotal: $" + (slider.Value * Price).ToString("###,###,###.00");
			lblNetCost.Text = "Total: $" + (slider.Value * Price * (1 + (Commission / 100))).ToString("###,###,###.00");
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			DialogResult = System.Windows.Forms.DialogResult.Cancel;
			Close();
		}

		private void bgw_DoWork(object sender, DoWorkEventArgs e)
		{
			string suggestions = "";
			NameValueCollection nvcResult = new NameValueCollection();

			// Look up current cash on hand
			string strResult;
			Dictionary<string, dynamic> result = null;
			double money;
			try {
				strResult = BLL.JsonLookups.Balance(username, password);
				result = BLL.JsonLookups.DeserializeJson(strResult); }
			catch {
				e.Result = new ApplicationException("Error looking up how much money you have. Cannot buy " + ticker.ToUpper() + ".");
				Close(); return; }
			if (strResult.Contains("User Has Exceeded Hourly Limit")) {
				e.Result = new ApplicationException("API Status: API limit exceeded. Empire Avenue resets this flag once per hour.");
				DialogResult = System.Windows.Forms.DialogResult.Cancel;
				Close(); return; }
			money = double.Parse(result["data"][0]["balance"].ToString()); 

			// Look up profile info: Price, share ownership info
			try {
				strResult = BLL.JsonLookups.ProfileInfo(username, password, ticker);
				result = BLL.JsonLookups.DeserializeJson(strResult); }
			catch {
				e.Result = new ApplicationException("Error looking up profile info for target ticker. Cannot buy " + ticker.ToUpper() + ".");
				Close(); return; }
			if (strResult.Contains("User Has Exceeded Hourly Limit")) {
				e.Result = new ApplicationException("API Status: API limit exceeded. Empire Avenue resets this flag once per hour.");
				DialogResult = System.Windows.Forms.DialogResult.Cancel;
				Close(); return; }
			double price = double.Parse(((Newtonsoft.Json.Linq.JObject)result["data"][0])["last_trade"].ToString());
			int owned = int.Parse(((Newtonsoft.Json.Linq.JObject)result["data"][0])["held_shares"].ToString()),
				AllowedToOwn = int.Parse(((Newtonsoft.Json.Linq.JObject)result["data"][0])["max_shares"].ToString()),
				shareholders_count = int.Parse(((Newtonsoft.Json.Linq.JObject)result["data"][0])["shareholders_count"].ToString()),
				AllowedToBuy = AllowedToOwn - owned;


			// Look up sale commission
			try {
				strResult = BLL.JsonLookups.Commission(username, password, ticker);
				result = BLL.JsonLookups.DeserializeJson(strResult); }
			catch {
				e.Result = new ApplicationException("Error looking up commission rates. Cannot buy " + ticker.ToUpper() + ".");
				Close(); return; }
			if (strResult.Contains("User Has Exceeded Hourly Limit")) {
				e.Result = new ApplicationException("API Status: API limit exceeded. Empire Avenue resets this flag once per hour.");
				DialogResult = System.Windows.Forms.DialogResult.Cancel;
				Close(); return; }
			double commission;
			try {
				commission = double.Parse(((Newtonsoft.Json.Linq.JObject)result["data"][0])["commission"].ToString()); }
			catch (KeyNotFoundException) {
				e.Result = new ApplicationException("Error looking up commission rates. Cannot buy " + ticker.ToUpper() + ".");
				Close(); return; }

			// You can afford the price plus 1/100 of the commission (5/100 = 5%), all divided into money available, and finally rounded down to the next lowest whole number.
			int CanAfford = (int)(Math.Floor(money / (price * (1 + (commission / 100)))));

			// Store share quantities
			nvcResult.Add("lblAllowed", "You are allowed " + AllowedToOwn.ToString() + " shares");
			nvcResult.Add("lblAfford", "You can afford " + CanAfford.ToString() + " shares");
			nvcResult.Add("lblOwned", "You currently own " + owned.ToString() + " shares");
			nvcResult.Add("lblCanBuy", "You can buy " + (AllowedToBuy < CanAfford ? AllowedToBuy : CanAfford).ToString() + " shares");
			nvcResult.Add("lblPrice", price.ToString());
			nvcResult.Add("lblCommission", commission.ToString());
			nvcResult.Add("slider", (AllowedToBuy < CanAfford ? AllowedToBuy : CanAfford).ToString());

			// Look up dividends

			// price/divsh ratio


			// Suggestions
			suggestions = "";
			if (shareholders_count > 100)
				suggestions += "This stock has " + shareholders_count.ToString() + " shareholders. Dividends may be low.\r\n";

			if (string.IsNullOrEmpty(txtSuggestions.Text.Trim()))
				suggestions = "Nothing out of the ordinary was detected on this transaction. Buy at your own discretion.\r\n";

			suggestions += "Note: The EaV API does not currently appear to expose Dividend information.\r\n  Therefore I cannot provide some detail and suggestions.\r\n";

			nvcResult.Add("suggestions", suggestions);
			e.Result = nvcResult;
		}

		private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			if (e.Result == null) {
				MessageBox.Show("An error occurred doing the lookups I need to buy stocks.");
				DialogResult = System.Windows.Forms.DialogResult.Cancel;
				Close();
				return; }

			if (e.Result.GetType() == typeof(Exception)) {
				MessageBox.Show(((Exception)e.Result).Message);
				DialogResult = System.Windows.Forms.DialogResult.Cancel;
				Close();
				return; }

			btnBuy.Enabled = true;
			slider.Enabled = true;

			NameValueCollection result = (NameValueCollection)e.Result;
			lblAllowed.Text = result["lblAllowed"];
			lblAfford.Text = result["lblAfford"];
			lblOwned.Text = result["lblOwned"];
			lblCanBuy.Text = result["lblCanBuy"];
			txtSuggestions.Text = result["suggestions"];
			slider.Maximum = int.Parse(result["slider"]);

			Price = double.Parse(result["lblPrice"]);
			Commission = double.Parse(result["lblCommission"]);
			lblCommission.Text = Commission.ToString() + "%";
			lblPrice.Text = Price.ToString("$###,###,###.00#####");
		}

		private void btnBuy_Click(object sender, EventArgs e)
		{
			string strResult = BLL.JsonPosts.Buy(username, password, ticker, slider.Value, Price);
			Dictionary<string, dynamic> result = BLL.JsonLookups.DeserializeJson(strResult);

			// shareholders_count = int.Parse(((Newtonsoft.Json.Linq.JObject)result["data"][0])["shareholders_count"].ToString()),
	
		}
	}
}
